﻿using JWT;
using JWT.Algorithms;
using JWT.Exceptions;
using JWT.Serializers;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.Data;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;

namespace ManYan.Common.jwt
{
    public class JwtHelper
    {
        /*刷新token,存redis或是数据库*/
        /// <summary>
        /// 生成一个刷新token
        /// </summary>
        /// <returns></returns>
        public string CreateRefreshToken()
        {
            return SnowFlakerHelper.CreateSnowFlakerId();
        }

      

        public string CreateJwt(JwtSetting jwtSetting)
        {
            var claims = new[]
                  {
                    new Claim(JwtRegisteredClaimNames.Nbf,$"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}") ,
                    new Claim (JwtRegisteredClaimNames.Exp,$"{new DateTimeOffset(DateTime.Now.AddMinutes(3000)).ToUnixTimeSeconds()}"),
                    new Claim(ClaimTypes.UserID, jwtSetting.UserId+string.Empty),
                    new Claim(ClaimTypes.UserNickName, jwtSetting.UserNickName+string.Empty),
                       new Claim(ClaimTypes.UserOrgID, jwtSetting.UserOrgId+string.Empty),
                       new Claim(ClaimTypes.RemoteIP, jwtSetting.RemoteIP+string.Empty),
                     new Claim(ClaimTypes.Role, string.Join(',',jwtSetting.RoleId+string.Empty))
                };
            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(JwtConst.SecurityKey));
            var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
            var token = new JwtSecurityToken(
                issuer: JwtConst.Issuer,
                audience: JwtConst.Issuer,
                claims: claims,
                expires: DateTime.Now.AddMinutes(3000),
                signingCredentials: creds);

            return new JwtSecurityTokenHandler().WriteToken(token);//返回token
        }
        /// <summary>
        /// jwt解密
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        public string DecodeJwt(string token)
        {
            var secret = JwtConst.SecurityKey;

            try
            {
                IJwtAlgorithm algorithm = new HMACSHA256Algorithm();//签名算法
                IJsonSerializer serializer = new JsonNetSerializer();//json序列化接口
                IDateTimeProvider provider = new UtcDateTimeProvider();
                IJwtValidator validator = new JwtValidator(serializer, provider);
                IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();//base64,jwt是基于base64编码
                IJwtDecoder decoder = new JwtDecoder(serializer, validator, urlEncoder, algorithm);
                var json = decoder.Decode(token, secret, verify: true);
                return json;


            }
            catch (TokenExpiredException ex)
            {
                throw ex;
            }
            catch (SignatureVerificationException ex)
            {
                throw ex;
            }


        }
    }


    public  static class ClaimTypes
    {
        public static string Role { get; set; } = "role";

        public static string UserID { get; set; } = "user_id";

        public static string UserNickName { get; set; } = "user_nickName";

        public static string UserOrgID { get; set; } = "user_orgId";

        public static string RemoteIP { get; set; } = "Remote_IP";


    }

    /// <summary>
    /// 密封类，表示这个类不能被继承
    /// </summary>
    public sealed class JwtSetting
    {
        public string? UserId { get; set; }
        public string? RoleId { get; set; }

        public string? UserNickName { get; set; }

        public string? UserOrgId { get; set; }

        public string? RemoteIP { get; set; }
    }
}
